using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using GurLoader;
using LogicNP.EZShellExtensions;

/*
The following steps are only necessary if adding a new shell extension to an existing 
ClassLibrary project via the "Add New Item.." dialog box.
These are automatically performed when create a brand new shell extensions project is
created using the "New Project" dialog box.

STEP 1 
If the project's AssemblyInfo.cs file has the AssemblyVersion 
atrribute with a variable version as follows :
[assembly: AssemblyVersion("1.0.*")]
...change it to a constant version as follows :
[assembly: AssemblyVersion("1.0.0.0")]

STEP 2
This assembly must be given a strong name so that it can be installed in the GAC.
To do so, generate a strong name key pair using the sn.exe tool that comes with the .Net SDK as follows :
sn.exe -k keypair.kp 
Then copy the generated keypair.kp file to the project directory and add the following attribute
to the project's AssemblyInfo.cs file
[assembly: AssemblyKeyFile("..\\..\\keypair.kp")]
*/

/*
USING POST-BUILD STEPS 
Use the following Post-Build Steps to speed up testing and developing of your shell extension : 

"{Path To RegisterExtensionDotNetXX.exe}" -i "$(TargetPath)"
"{Path To RestartExplorer.exe}"

The first step registers the shell extension on the system and installs the dll in the GAC after 
every build. The second step restarts Windows Explorer so that your newly built dll gets loaded 
by Windows Explorer.

Example : 
"C:\Program Files\LogicNP Software\EZShellExtensions.Net\RegisterExtensionDotNetXX.exe" -i "$(TargetPath)"
"C:\Program Files\LogicNP Software\EZShellExtensions.Net\RestartExplorer.exe"

For Visual Studio 2002/2003 (.Net 1.0, 2.0), use RegisterExtensionDotNet10.exe
For Visual Studio 2005/2005 (.Net 2.0, 3.0, 3.5), use RegisterExtensionDotNet20.exe
For Visual Studio 2010 (.Net 4.0), use RegisterExtensionDotNet40.exe

See the topic "Using Post-Build Steps to ease testing of shell extensions" in the EZShellExtensions.Net 
help file for more information.
*/


namespace GurLoaderHelper
{
    // The GuidAttribute has been applied to the extension class
    // with an automatically generated unique GUID.
    // Every different extension should have such a unique GUID
    [Guid("EED98B3E-8B1B-4E87-B127-BD87AACA0F6F")]
    [ComVisible(true)]
    // The TargetExtension attribute has been applied below to indicate 
    // the file types that your extension targets. 
    // TODO : Change the extension below to your desired extension.
    //[TargetExtension(SpecialProgIDTargets.AllFiles,false)]
    [TargetExtension("jpegfile", false)]
    public class SendToImgurExtension : ContextMenuExtension
    {

        public SendToImgurExtension() : base()
        {
        }

        static SendToImgurExtension() 
        { 
            //AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 
        } 

        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
        { 
            if (args.Name.Contains("GurLoader.Common")) // .Net runtime is trying to load Dependant.dll assembly 
            { 
                // Load it from the same path as our shell extension dll and return it 
                string path = Assembly.GetExecutingAssembly().Location; 
                path = Path.GetDirectoryName(path); 
                path = Path.Combine(path, "GurLoader.Common.dll"); 
                Assembly ret = Assembly.LoadFrom(path); 
                return ret; 
            }

            if (args.Name.Contains("MailSlot")) // .Net runtime is trying to load Dependant.dll assembly 
            {
                // Load it from the same path as our shell extension dll and return it 
                string path = Assembly.GetExecutingAssembly().Location;
                path = Path.GetDirectoryName(path);
                path = Path.Combine(path, "MailSlot.dll");
                Assembly ret = Assembly.LoadFrom(path);
                return ret;
            } 

            return null; 
        }

        public const string MailslotName = "GurLoader";

        private readonly IMessageSender messageSender = new MailslotMessageSender(MailslotName);

        private IMessageSender MessageSender
        {
            get { return messageSender; }
        }

        // Override this method to perform initialzation specific to your contextmenu extension. 
        protected override bool OnInitialize()
        {
            // TODO : Add your initialization code here
            return true;
        }

        // Override this method to add your menu items to the context menu
        protected override void OnGetMenuItems(LogicNP.EZShellExtensions.GetMenuitemsEventArgs e)
        {
            ShellMenuItem parent = e.Menu.AddItem("Send To Imgur");
            parent.HasSubMenu = true;
            parent.SubMenu.AddItem("Send Images", "sendImages", "Send one or more images to Imgur");
            parent.SubMenu.AddItem("Send Album", "sendAlbum", "Send an album of images to Imgur");
        }


        // Override this method to perform your own tasks when any of the 
        // menu items provided by your contextmenu extension is selected by the user.
        protected override bool OnExecuteMenuItem(LogicNP.EZShellExtensions.ExecuteItemEventArgs e)
        {
            // TODO : Add your code here
            if (e.MenuItem.Verb == "sendImages")
            {
                ExecuteCommand(Command.SendImages);
                return true;
            }
            else if (e.MenuItem.Verb == "sendAlbum")
            {
                ExecuteCommand(Command.SendAlbum);
                return true;
            }

            // Return TRUE if menu item is yours(check verb) and execution is successful, FALSE otherwise
            return false;
        }

        private void ExecuteCommand(Command command)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("{0} ", command);
            foreach (var selectedItemPath in TargetFiles)
            {
                sb.AppendFormat("\"{0}\" ", selectedItemPath);
            }

            MessageSender.SendMessage(sb.ToString());
        }

        // Override this method to provide the dimensions for any owner drawn 
        // contextmenu items provided by your contextmenu extension.
        // TODO : UNCOMMENT THIS OVERRIDE IF YOU HAVE OWNER DRAWN MENU IETMS
        /*
        protected override void OnMeasureMenuItem(LogicNP.EZShellExtensions.EZSMeasureItemEventArgs e)
        {
            // TODO : Set menu item width and height
            e.ItemHeight = e.ItemWidth = 150;
        }
        */


        // Override this method to draw any owner-draw menu items
        // added by the contextmenu extension.
        // TODO : UNCOMMENT THIS OVERRIDE IF YOU HAVE OWNER DRAWN MENU IETMS
        /*
        protected override void OnDrawMenuItem(LogicNP.EZShellExtensions.EZSDrawItemEventArgs e)
        {
            // TODO : Write your drawing code here.
            e.Graphics.FillRectangle(SystemBrushes.Menu,e.Bounds);
        }
        */

        // Your assembly should have one static method marked with the 
        // ComRegisterFunction attribute. The function should return void and take 
        // one parameter whose type is System.Type.
        // 
        // This method is used to register the extension on the system by calling the
        // RegisterExtension method.
        //
        [ComRegisterFunction]
        public static void Register(System.Type t)
        {
            ContextMenuExtension.RegisterExtension(typeof(SendToImgurExtension));
        }

        // Your assembly should have one static method marked with the 
        // ComUnregisterFunction attribute. The function should return void and take 
        // one parameter whose type is System.Type.
        // 
        // This method is used to register the extension on the system by calling the
        // UnRegisterExtension method.
        //
        [ComUnregisterFunction]
        public static void UnRegister(System.Type t)
        {
            ContextMenuExtension.UnRegisterExtension(typeof(SendToImgurExtension));
        }


    }
}